//
//  Http.m
//  AGG_V2
//
//  Created by admin on 15/5/12.
//  Copyright (c) 2015年 admin. All rights reserved.
//

#import "Http.h"
#import "AFNetworking.h"
#import "AppDelegate.h"
#import "UIControl+acceptEvent.h"


static NSUInteger const kTokenInvalid = 409;

@interface Http ()

@property (nonatomic, copy) NSString *clientType;

@end

@implementation Http

- (instancetype)init {
    [NSException raise:@"SingletonException" format:@"Http cannot be initialized using init"];
    
    return nil;
}

+ (instancetype)sharedInstance {
    static Http *sharedInstance = nil;
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[Http alloc] initWithClientType:@"iOS"];
    });
    
    return sharedInstance;
}

- (instancetype)initWithClientType:(NSString *)clientType {
    if (self = [super init])
        self.clientType = clientType;
    
    return self;
}

- (NSURLSessionDataTask *)requestForMethod:(Methods)Meth
                                       Url:(NSString *)url
                                withParams:(NSDictionary *)params
                                completion:(DataDownloadCompletion)completion{
    if (!completion)
        return nil;

    NSURLSessionDataTask *NSURLSessionDataTa;
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.requestSerializer    = [AFHTTPRequestSerializer serializer];
    
    if ([MYY_User readUserFromFile].token && ![[MYY_User readUserFromFile].token isEqualToString:@""]) {
        [manager.requestSerializer setValue:[MYY_User readUserFromFile].token forHTTPHeaderField:@"accessusertoken"];
    }
  
    // 响应序列化器
    manager.responseSerializer = ({
        AFJSONResponseSerializer *serializer = [AFJSONResponseSerializer serializer];
        serializer.removesKeysWithNullValues = YES;
        serializer;
    });
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html", nil];
    
    if (isIOS9) {
        url= [[NSString stringWithFormat:@"%@%@",MYXBaseUrl,url] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    }else {
        url=[[NSString stringWithFormat:@"%@%@",MYXBaseUrl,url] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    }
    
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    [params enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
        [dict setObject:obj forKey:key];
    }];
    /*
    NSString *currentVersion = info[@"CFBundleShortVersionString"];//Version
    
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    dict[@"client_type"]      = self.clientType;
    dict[@"version_name"]     = currentVersion;
    
   
    [params enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
        [dict setObject:obj forKey:key];
    }];
     */
    
#ifdef DEBUG
    // 打印HTTP请求的URL
    [self printRequestMethod:Meth Url:url params:dict];
#endif
    if (Meth == POST) {
       // NSString *urlWithVersionName = [url stringByAppendingFormat:@"?version_name=%@",currentVersion];
        
     NSURLSessionDataTa = [manager POST:url parameters:dict progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            [self sendAction];
            if ([responseObject[@"status"] intValue] == kTokenInvalid) {
                 [MYY_User readUserFromFile].isLogin = NO;
                [[NSNotificationCenter defaultCenter] postNotificationName:MYX_LoginOutNotificationName object:nil];
                return;
            }
           [self requestSuccessForTask:task responseObject:responseObject completion:completion];
            
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            NSData *data = error.userInfo[@"com.alamofire.serialization.response.error.data"];
            if (data) {
                NSDictionary *errorDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
                NSString *status = errorDict[@"status"];
                NSString *msg = errorDict[@"message"];
                if (status.intValue == -1) {
                    [MYY_User readUserFromFile].isLogin = NO;
                    [[NSNotificationCenter defaultCenter] postNotificationName:MYX_LoginOutNotificationName object:nil];
                    
                }else{
                    ShowSVProgressErrorMessage(msg);
                }
                [self sendAction];
                [self requestFailureForTask:task error:error completion:completion];
            }
           
        }];

    } else {
    
       NSURLSessionDataTa= [manager GET:url parameters:dict progress:^(NSProgress * _Nonnull downloadProgress) {
            
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            [self sendAction];
            if ([responseObject[@"status"] intValue] == kTokenInvalid) {
                [[NSNotificationCenter defaultCenter] postNotificationName:MYX_LoginOutNotificationName object:nil];
                return;
            }
            
            [self requestSuccessForTask:task responseObject:responseObject completion:completion];
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            [SVProgressHUD dismiss];
            NSData *data = error.userInfo[@"com.alamofire.serialization.response.error.data"];
            if (data) {
                NSDictionary *errorDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
                NSString *msg = errorDict[@"message"];
                NSString *status = errorDict[@"status"];
                if (status.intValue == -1) {
                     [MYY_User readUserFromFile].isLogin = NO;
                    [[NSNotificationCenter defaultCenter] postNotificationName:MYX_LoginOutNotificationName object:nil];
                }else{
                    ShowSVProgressErrorMessage(msg);
                }

                [self sendAction];
                [self requestFailureForTask:task error:error completion:completion];
            }
           
        }];
       
        
    }
    return NSURLSessionDataTa;
}

- (NSURLSessionDataTask *)uploadDataWithUrl:(NSString *)url withParams:(NSDictionary *)params constructingBodyWithBlock:(void (^)(id<AFMultipartFormData>))block completion:(DataDownloadCompletion)completion {
    if (!completion) {
        return nil;
    }
    
    NSURLSessionDataTask *NSURLSessionDataTa;
    
    //1.创建管理者对象
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.requestSerializer              = [AFHTTPRequestSerializer serializer];
    manager.responseSerializer             = [AFJSONResponseSerializer serializer];
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html", nil];
    
    /*
    
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
   

    NSDictionary *info       = [[NSBundle mainBundle] infoDictionary];
    NSString *currentVersion = info[@"CFBundleShortVersionString"];//Version

    dict[@"client_type"] = self.clientType;
    dict[@"version_name"]     = currentVersion;

    [params enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
        [dict setObject:obj forKey:key];
    }];

    NSString *urlWithVersionName = [url stringByAppendingFormat:@"?version_name=%@",currentVersion];
     */
    if ([MYY_User readUserFromFile].token && ![[MYY_User readUserFromFile].token isEqualToString:@""]) {
        
        [manager.requestSerializer setValue:[MYY_User readUserFromFile].token forHTTPHeaderField:@"accessusertoken"];
    }
    
    if (isIOS9) {
        url= [[NSString stringWithFormat:@"%@%@",MYXBaseUrl,url] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    }else {
        url=[[NSString stringWithFormat:@"%@%@",MYXBaseUrl,url] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    }
    
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    NSURLSessionDataTa=  [manager POST:url parameters:dict constructingBodyWithBlock:^(id<AFMultipartFormData>formData) {
        if (block) {
            block(formData);
        };
    } progress:^(NSProgress * _Nonnull uploadProgress) {
    
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [self sendAction];
        if ([responseObject[@"status"] intValue] == kTokenInvalid) {
            [[NSNotificationCenter defaultCenter] postNotificationName:@"tokenInvalid" object:nil];
            return;
        }
        [self requestSuccessForTask:task responseObject:responseObject completion:completion];
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [SVProgressHUD dismiss];

        NSData *data = error.userInfo[@"com.alamofire.serialization.response.error.data"];
        if (data) {
            NSDictionary *errorDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
            NSString *status = errorDict[@"status"];
            NSString *msg = errorDict[@"message"];
            if (status.intValue == -1) {
                 [MYY_User readUserFromFile].isLogin = NO;
                [[NSNotificationCenter defaultCenter] postNotificationName:MYX_LoginOutNotificationName object:nil];
            }else{
                ShowSVProgressErrorMessage(msg);
            }

        }
        [self sendAction];
        [self requestFailureForTask:task error:error completion:completion];
       
    }];
    
    return NSURLSessionDataTa;
}

/**
上传图像
 */
- (NSURLSessionDataTask *)uploadImgDataWithUrl:(NSString *)url withParams:(NSDictionary *)params constructingBodyWithBlock:(void (^)(id<AFMultipartFormData>))block progress:(void(^)(NSProgress * _Nonnull uploadProgress))progress completion:(DataDownloadCompletion)completion {
    if (!completion) {
        return nil;
    }
    
    NSURLSessionDataTask *NSURLSessionDataTa;
    //1.创建管理者对象
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.requestSerializer              = [AFHTTPRequestSerializer serializer];
    manager.responseSerializer             = [AFJSONResponseSerializer serializer];
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html", nil];
    
    /*
     
     NSMutableDictionary *dict = [NSMutableDictionary dictionary];
     
     
     NSDictionary *info       = [[NSBundle mainBundle] infoDictionary];
     NSString *currentVersion = info[@"CFBundleShortVersionString"];//Version
     
     dict[@"client_type"] = self.clientType;
     dict[@"version_name"]     = currentVersion;
     
     [params enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
     [dict setObject:obj forKey:key];
     }];
     
     NSString *urlWithVersionName = [url stringByAppendingFormat:@"?version_name=%@",currentVersion];
     */
    if ([MYY_User readUserFromFile].token && ![[MYY_User readUserFromFile].token isEqualToString:@""]) {
        
        [manager.requestSerializer setValue:[MYY_User readUserFromFile].token forHTTPHeaderField:@"accessusertoken"];
    }
    
    if (isIOS9) {
        url= [[NSString stringWithFormat:@"%@%@",MYXBaseUrl,url] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    }else {
        url=[[NSString stringWithFormat:@"%@%@",MYXBaseUrl,url] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    }
    
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    NSURLSessionDataTa=  [manager POST:url parameters:dict constructingBodyWithBlock:^(id<AFMultipartFormData>formData) {
        if (block) {
            block(formData);
        };
    } progress:^(NSProgress * _Nonnull uploadProgress) {
        if (progress) {
            progress(uploadProgress);
        }
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [self sendAction];
        if ([responseObject[@"status"] intValue] == kTokenInvalid) {
             [MYY_User readUserFromFile].isLogin = NO;
            [[NSNotificationCenter defaultCenter] postNotificationName:MYX_LoginOutNotificationName object:nil];
            return;
        }
        [self requestSuccessForTask:task responseObject:responseObject completion:completion];
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [SVProgressHUD dismiss];

        NSData *data = error.userInfo[@"com.alamofire.serialization.response.error.data"];
        if (data) {
            NSDictionary *errorDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
            NSString *status = errorDict[@"status"];
            NSString *msg = errorDict[@"message"];
                             
            if (status.intValue == -1) {
                 [MYY_User readUserFromFile].isLogin = NO;
                [[NSNotificationCenter defaultCenter] postNotificationName:MYX_LoginOutNotificationName object:nil];
            }else{
                ShowSVProgressErrorMessage(msg);
            }

            [self sendAction];
            [self requestFailureForTask:task error:error completion:completion];
        }
        
        
    }];
    
    return NSURLSessionDataTa;
}
- (void)sendAction {
    AppDelegate *appDelegate = (AppDelegate *) [UIApplication sharedApplication].delegate;
    
    if (appDelegate.clickControl) {
        appDelegate.clickControl.agg_ignoreEvent = NO;
    }
}

#pragma mark - Session
- (NSURLSessionDataTask *)sessionRequestForMethod:(Methods)Meth Url:(NSString *)url withParams:(NSDictionary<NSString *, id> *)params completion:(DataDownloadCompletion)completion {
    if (!completion) {
        return nil;
    }
    
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.requestSerializer = [AFHTTPRequestSerializer serializer];
    manager.responseSerializer = ({
        AFJSONResponseSerializer *serializer = [AFJSONResponseSerializer serializer];
        serializer.removesKeysWithNullValues = YES;
        serializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html", nil];
        serializer;
    });
    
    if ([MYY_User readUserFromFile].token && ![[MYY_User readUserFromFile].token isEqualToString:@""]) {
        
        [manager.requestSerializer setValue:[MYY_User readUserFromFile].token forHTTPHeaderField:@"accessusertoken"];
    }

    NSMutableDictionary *dictM = [NSMutableDictionary dictionary];
    
    [params enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
        [dictM setObject:obj forKey:key];
    }];

    /*
    NSDictionary *info = [NSBundle mainBundle].infoDictionary;
    NSString *currentVersion = info[@"CFBundleShortVersionString"];
    
    NSMutableDictionary *dictM = [NSMutableDictionary dictionary];
    [dictM setObject:self.clientType forKey:@"client_type"];
    [dictM setObject:currentVersion forKey:@"version_name"];
    [dictM addEntriesFromDictionary:params];
     */
    
    if (isIOS9) {
        url= [[NSString stringWithFormat:@"%@%@",MYXBaseUrl,url] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    }else {
        url=[[NSString stringWithFormat:@"%@%@",MYXBaseUrl,url] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    }
#ifdef DEBUG
    // 打印HTTP请求的URL
    [self printRequestMethod:Meth Url:url params:dictM];
#endif
    NSURLSessionDataTask *currentDataTask;
     if (Meth == POST) {
        
        currentDataTask = [manager POST:url parameters:dictM progress:^(NSProgress * _Nonnull uploadProgress) {
            
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
             [self requestSuccessForTask:task responseObject:responseObject completion:completion];
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
              [self requestFailureForTask:task error:error completion:completion];
        }];
       
    } else {
        currentDataTask = [manager GET:url parameters:dictM progress:^(NSProgress * _Nonnull downloadProgress) {
            
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
             [self requestSuccessForTask:task responseObject:responseObject completion:completion];
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
             [self requestFailureForTask:task error:error completion:completion];
        }];
    }
    return currentDataTask;
}

#pragma mark - Other

/** 网络请求 - 成功 */
- (void)requestSuccessForTask:(NSURLSessionDataTask * _Nullable)task responseObject:(id  _Nullable)responseObject completion:(DataDownloadCompletion)completion {
    [self sendAction];
    
    if ([responseObject[@"status"] intValue] == kTokenInvalid) {
         [MYY_User readUserFromFile].isLogin = NO;
        [[NSNotificationCenter defaultCenter] postNotificationName:MYX_LoginOutNotificationName object:nil];
        return;
    }
    completion(responseObject, nil);
}

/** 网络请求 - 失败 */
- (void)requestFailureForTask:(NSURLSessionDataTask * _Nullable)task error:(NSError *)error completion:(DataDownloadCompletion)completion {
    [self sendAction];
    completion(nil, error);
}

#pragma mark - Util

/**
 *  打印HTTP请求的URL
 *
 *  @param urlString URL字符串
 *  @param params    参数字典
 */
- (void)printRequestMethod:(Methods)Meth Url:(NSString *)urlString params:(NSDictionary *)params {
    NSMutableString *totalUrl = [NSMutableString stringWithFormat:@"%@?", urlString];
    [params enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        if (obj) {
            [totalUrl appendString:[NSString stringWithFormat:@"&%@=%@", key, obj]];
        }
    }];
    NSLog(@"%@请求 = %@", Meth == POST ? @"POST" : @"GET", totalUrl);
}

@end
